----------------Pentapus---------------
A 4am crack                  2019-05-28
---------------------------------------

Name: Pentapus
Genre: action
Year: 1983
Publisher: Turning Point Software
Platform: Apple ][+ or later
Media: 5.25-inch disk
Sides: 1
OS: DOS 3.3

                   ~

               Chapter 0
 In Which Various Automated Tools Fail
          In Interesting Ways


COPYA
  fails on last pass

Locksmith Fast Disk Backup
  unable to read tracks $21 and $22

EDD 4 bit copy (no sync, no count)
  errors on T21 and T22
  copy boots but immediately says
  "INVALID DISKETTE!
   RETURN TO TURNING POINT SOFTWARE"

I will not be doing that.

Copy ][+ nibble editor
  T21 seems unformatted
  T22 is almost entirely $FF nibbles
  with some $D5 and a few other
  scattered ones thrown in for good
  measure

Disk Fixer
  DOS 3.3-style bootloader but no DOS
  no disk catalog on track $11
  game loads straight from RWTS reads

Why didn't COPYA work?
  specially formatted tracks at the end
  of the disk

Why didn't Locksmith FDB work?
  likewise

Why didn't my EDD copy work?
  unclear -- protection check looking
  at track $22 that couldn't copy
  properly?

Next steps:

  1. Trace the boot
  2. Disable the protection check
  3. Declare victory (*)

(*) go to the gym

                   ~

               Chapter 1
        In Which It's All Over
           But The Screaming


Turning to my trusty Disk Fixer sector
editor, track 0 starts off as a normal
DOS 3.3-shaped bootloader before
jumping to $B700 (stored on sector 1).
We shall pick up the action there.

T00,S01
----------- DISASSEMBLY MODE ----------
0000:8E E9 B7       STX   $B7E9
0003:8E F7 B7       STX   $B7F7
0006:A9 01          LDA   #$01
0008:8D F8 B7       STA   $B7F8
000B:8D EA B7       STA   $B7EA
000E:AD C2 B7       LDA   $B7C2
0011:8D C3 B7       STA   $B7C3
0014:8A             TXA
0015:4A             LSR
0016:4A             LSR
0017:4A             LSR
0018:4A             LSR
0019:AA             TAX
001A:A9 00          LDA   #$00
001C:9D F8 04       STA   $04F8,X
001F:9D 78 04       STA   $0478,X
0022:20 79 B7       JSR   $B779
...

; priming for an RWTS read into $0800
0079:A9 08          LDA   #$08
007B:8D F1 B7       STA   $B7F1
007E:8D 97 B7       STA   $B797

; sector $0C
0081:A9 0C          LDA   #$0C
0083:8D ED B7       STA   $B7ED

; track $00
0086:A9 00          LDA   #$00
0088:8D EC B7       STA   $B7EC
008B:A9 01          LDA   #$01
008D:8D F4 B7       STA   $B7F4
0090:20 98 B7       JSR   $B798
0093:B0 E4          BCS   $0079

; self-modified earlier (at $B77E) to
; jump to $0800 after reading
0095:4C 00 FF       JMP   $FF00
0098:A9 B7          LDA   #$B7
009A:A0 E8          LDY   #$E8
009C:4C B5 B7       JMP   $B7B5

OK, let's look at track 0, sector $0C.

T00,S0C
----------- DISASSEMBLY MODE ----------
0000:4C 85 08       JMP   $0885
...

; will examine this in a moment
0085:20 03 08       JSR   $0803

; turn off drive motor
0088:BD 88 C0       LDA   $C088,X

; carry clear = success
008B:90 F7          BCC   $0084

; The Badlands -- clear the screen and
; display the error message I saw on my
; non-working copy
008D:20 58 FC       JSR   $FC58
0090:A0 84          LDY   #$84
0092:99 00 08       STA   $0800,Y
0095:88             DEY
0096:D0 FA          BNE   $0092
0098:8C F4 03       STY   $03F4
009B:B9 B2 08       LDA   $08B2,Y
009E:F0 06          BEQ   $00A6
00A0:99 34 04       STA   $0434,Y
00A3:C8             INY
00A4:D0 F5          BNE   $009B
00A6:A8             TAY
00A7:B9 C4 08       LDA   $08C4,Y
00AA:F0 E4          BEQ   $0090
00AC:99 2C 05       STA   $052C,Y
00AF:C8             INY
00B0:D0 F5          BNE   $00A7

OK, so the subroutine at $0803 very
much needs to return with the carry
clear.

; set up another RWTS call, on
; track $22 (the mystery track!)
0003:A9 22          LDA   #$22
0005:8D EC B7       STA   $B7EC

; seek only
0008:A9 00          LDA   #$00
000A:8D F4 B7       STA   $B7F4

; patch RWTS to return without turning
; off the drive motor
000D:A9 60          LDA   #$60
000F:8D 4D BE       STA   $BE4D

; seek to track $22
0012:A0 E8          LDY   #$E8
0014:A9 B7          LDA   #$B7
0016:20 00 BD       JSR   $BD00

; restore code we just patched
0019:A9 BD          LDA   #$BD
001B:8D 4D BE       STA   $BE4D
001E:B0 64          BCS   $0084

; the meat of the protection check --
; reading and counting nibbles on the
; mystery track $22
0020:BD 8C C0       LDA   $C08C,X
0023:10 FB          BPL   $0020
0025:48             PHA
0026:68             PLA
0027:C9 D5          CMP   #$D5
0029:D0 F5          BNE   $0020

; initial counter
002B:A0 00          LDY   #$00
002D:84 FE          STY   $FE

; find next $D5 or $F7 nibble
002F:BD 8C C0       LDA   $C08C,X
0032:10 FB          BPL   $002F
0034:C9 D5          CMP   #$D5
0036:F0 0D          BEQ   $0045
0038:C9 F7          CMP   #$F7
003A:D0 01          BNE   $003D

; meanwhile, count the nibbles in
; between (the non-$D5/$F7 nibbles are
; $FF, so this is a fancy way of
; subtracting 1 from zero page $FE)
003C:C8             INY
003D:18             CLC
003E:65 FE          ADC   $FE
0040:85 FE          STA   $FE
0042:4C 2F 08       JMP   $082F
0045:98             TYA
0046:F0 E3          BEQ   $002B

; find next $D5 nibble
0048:BD 8C C0       LDA   $C08C,X
004B:10 FB          BPL   $0048
004D:48             PHA
004E:68             PLA
004F:C9 FF          CMP   #$FF
0051:F0 F5          BEQ   $0048
0053:C9 D5          CMP   #$D5
0055:F0 24          BEQ   $007B

; skip next 5 nibbles
0057:A0 05          LDY   #$05
0059:BD 8C C0       LDA   $C08C,X
005C:10 FB          BPL   $0059
005E:48             PHA
005F:68             PLA
0060:88             DEY
0061:D0 F6          BNE   $0059

; find next $D5 nibble
0063:BD 8C C0       LDA   $C08C,X
0066:10 FB          BPL   $0063
0068:48             PHA
0069:68             PLA
006A:C9 FF          CMP   #$FF
006C:F0 F5          BEQ   $0063
006E:C9 D5          CMP   #$D5
0070:D0 09          BNE   $007B

; next nibble must be $FF
0072:BD 8C C0       LDA   $C08C,X
0075:10 FB          BPL   $0072
0077:C9 FF          CMP   #$FF
0079:F0 02          BEQ   $007D

; otherwise we fail and return to the
; caller
007B:38             SEC
007C:60             RTS

; and the previous count must be #$F0
; or some multiple of #$100 that wraps
; around to #$F0
007D:A5 FE          LDA   $FE
007F:C9 10          CMP   #$10
0081:D0 F8          BNE   $007B

; as we figured out already by looking
; at the caller, this subroutine clears
; the carry bit on success
0083:18             CLC
0084:60             RTS

This patch will change the protection
subroutine at $0803 so it clears the
carry and returns.

T00,S0C,$03: A922 -> 1860

Quod erat liberandum.

---------------------------------------
A 4am crack                    No. 2033
------------------EOF------------------
